//
//  TTOSS.swift
//  TTBLL
//
//  Created by Toj on 4/15/21.
//

import Foundation

public typealias TTOSSUploadProgress = ((_ sentByte: Int64, _ totalSentByte: Int64, _ totalByte: Int64) -> Void)
public typealias TTOSSUploadCompleted = ((_ isSuccess: Bool, _ info: String) -> Void)

public typealias TTOSSDownloadProgress = ((_ bytesWritten: Int64, _ totalBytesWritten: Int64, _ totalBytes: Int64) -> Void)
public typealias TTOSSDownloadCompleted = ((_ isSuccess: Bool, _ data: Data?, _ info: String) -> Void)

open class TTOSS: NSObject {
    
    fileprivate var server: TTOSSServer!
    fileprivate var aResource: OSSResource?
    
    private override init() { }
    
    public init(url resource: OSSResource) {
        super.init()
        
        aResource = resource
        server = TTOSSServer(endpoint: resource.endpoint, serverUrl: resource.serverUrl)
    }
    
    public init(resource: OSSResource, serverUrl: String) {
        super.init()
        
        aResource = resource
        server = TTOSSServer(endpoint: resource.endpoint, serverUrl: serverUrl)
    }
    
    public init(resource: OSSResource) {
        super.init()
        
        aResource = resource
        server = TTOSSServer(endpoint: resource.endpoint, accessKey: resource.accessKey, secretKey: resource.secretKey, token: resource.token, expiration: resource.expiration)
    }
}

public extension TTOSS {
    
    func upload(progress: TTOSSUploadProgress? = nil,
                completed: TTOSSUploadCompleted? = nil) {
        guard let resource = aResource else { return }
        
        upload(from: resource.fromURL,
               progress: progress,
               completed: completed)
    }
    
    func upload(from url: String,
                progress: TTOSSUploadProgress? = nil,
                completed: TTOSSUploadCompleted? = nil) {
        guard let resource = aResource else { return }
        
        server.upload(bucket: resource.bucketName,
                      object: resource.objectKey,
                      from: url)
        { (bytesSent, totalByteSent, totalBytes) in
            print("bytesSent: \(bytesSent), totalByteSent: \(totalByteSent), totalBytes: \(totalBytes)")
        } completed: { (error) in
            guard completed != nil else { return }
            
            var info = "文件上传成功"
            var isSuccess = true
            if error != nil {
                isSuccess = false
                info = "文件上传失败, 原因未知"
                if let error = error as NSError?, let userInfo = error.userInfo.tt_toJson {
                    info = userInfo
                }
            }
            
            completed?(isSuccess, info)
        }
    }
    
    func upload(data: Data,
                progress: TTOSSUploadProgress? = nil,
                completed: TTOSSUploadCompleted? = nil) {
        guard let resource = aResource else { return }
        server.upload(bucket: resource.bucketName,
                      object: resource.objectKey,
                      data: data)
        { (bytesSent, totalByteSent, totalBytes) in
            print("bytesSent: \(bytesSent), totalByteSent: \(totalByteSent), totalBytes: \(totalBytes)")
        } completed: { (error) in
            guard completed != nil else { return }
            
            var info = "文件上传成功"
            var isSuccess = true
            if error != nil {
                isSuccess = false
                info = "文件上传失败, 原因未知"
                if let error = error as NSError?, let userInfo = error.userInfo.tt_toJson {
                    info = userInfo
                }
            }
            
            completed?(isSuccess, info)
        }
    }
}

public extension TTOSS {
    
    func download(to url: String = "",
                  progress: TTOSSDownloadProgress? = nil,
                  completed: TTOSSDownloadCompleted? = nil) {
        guard let resource = aResource else { return }
        let toURL = url.count == 0 ? resource.toURL : url
        
        server.download(bucket: resource.bucketName,
                        object: resource.objectKey,
                        to: toURL)
        { (bytesWritten, totalBytesWritten, totalBytes) in
            print("bytesWritten: \(bytesWritten), totalBytesWritten: \(totalBytesWritten), totalBytes: \(totalBytes)")
            progress?(bytesWritten, totalBytesWritten, totalBytes)
        } completed: { (error, data) in
            guard completed != nil else { return }
            
            var info = "文件下载成功"
            var isSuccess = true
            if error != nil {
                isSuccess = false
                info = "文件下载失败, 原因未知"
                if let error = error as NSError?, let userInfo = error.userInfo.tt_toJson {
                    info = userInfo
                }
            }
            
            completed?(isSuccess, data, info)
        }
    }
}
